/*
 * AutoPushingTrigger.java       1.0    2011-7-12
 *
 * Copyright (c) 2010, 2011 Citiway Technology(Tianjin) Co., Ltd.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Citiway Technology(Tianjin) Co., Ltd. ("Confidential Information"). 
 * You shall not disclose such Confidential Information and shall use 
 * it only in accordance with the terms of the license agreement you 
 * entered into with Citiway.
 */
package cn.com.generaldata.os.job;

import java.text.ParseException;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.generaldata.os.constant.BillboardConstant;
import cn.com.generaldata.os.constant.FilterConstant;
import cn.com.generaldata.os.dao.intf.BaseDAOInterface;
import cn.com.generaldata.os.paging.Filter;
import cn.com.generaldata.os.paging.FilterRule;
import cn.com.generaldata.os.pojo.BillboardIndustry;
import cn.com.generaldata.os.pojo.Unit;
import cn.com.generaldata.os.pojo.User;
import cn.com.generaldata.os.util.MD5Util;
import cn.gbase.ocean.js.cas.UserSyncMessage;
import cn.gbase.ocean.js.cas.UserSyncMessageCenter;

/**
 * @Class AutoPushingScheduler.java
 * 
 * @author Stoner.Wong 上午09:31:37
 * 
 *         $Id$
 */
public class AutoPushingScheduler {

	private static final String GROUP_AUTO_PUSHING = "groupAutoPushing";
	private static Scheduler scheduler = null;
	private BaseDAOInterface<User> userDAO;
	private BaseDAOInterface<Unit> unitDAO;

	private final ExecutorService es = Executors.newSingleThreadScheduledExecutor();

	private static final Logger logger = LoggerFactory.getLogger(AutoPushingScheduler.class);

	public void setUnitDAO(BaseDAOInterface<Unit> unitDAO) {
		this.unitDAO = unitDAO;
	}

	private BaseDAOInterface<BillboardIndustry> billboardIndustryDAO;

	public void setUserDAO(BaseDAOInterface<User> userDAO) {
		this.userDAO = userDAO;
	}

	public void init() throws SchedulerException, ParseException {
		Runnable task = new Runnable() {

			@Override
			public void run() {
				while (true) {

					UserSyncMessage msg = UserSyncMessageCenter.takeMsg();
					if (msg != null) {
						logger.info("接收到同步用户信息 ,用户名 : {},消息类型:{}", msg.getUsername(), msg.getType());
						switch (msg.getType()) {
						case Add:
						// 增加用户
						{
							Filter filter = new Filter();
							filter.addRule(new FilterRule(FilterConstant.EQUAL, "userLoginname", msg.getUsername()));
							filter.addRule(new FilterRule(FilterConstant.EQUAL, "enterpriseUserUseSystem", 1));
							List<User> users = userDAO.find(User.class, filter, null);
							logger.info("users 是否需要添加：{}", users.isEmpty());
							if (users.isEmpty()) {
								String hql = "from Unit where role.id='3'";
								List<Unit> list = unitDAO.findEntitiesByHql(hql, 1, 1, null);
								Unit unit = list.get(0);
								User user = new User();
								user.setId(UUID.randomUUID().toString().replaceAll("-", ""));
								user.setUserLoginname(msg.getUsername());
								user.setUserPasswd(MD5Util.getMD5ofStr("12345678"));
								user.setUserFlag("0");
								user.setEnterpriseUserUseSystem(1);
								user.setUserUnit(unit);
								user.setUserContactPhone(unit.getTel());
								user.setUserContactPerson(unit.getFr());
								user.setRole(unit.getRole());
								user.setArea(unit.getArea());
								user.setUserReportedDataType("2");
								user.setUserInstitutionCode(unit.getUnitInstitutionCode());
								user.setUserInstitutionName(unit.getUnitInstitutionName());
								user.setUserFaxTel(unit.getFax());
								user.setProduct1(unit.getProduct1());
								user.setProduct2(unit.getProduct2());
								user.setProduct3(unit.getProduct3());
								user.setPractitioner(unit.getPractitioner());
								user.setSuperCompanyCode(unit.getSuperCompanyCode());
								user.setLm(unit.getLm());
								user.setAddr(unit.getAddr());
								user.setRegistAdd(unit.getRegistAdd());
								user.setQh(unit.getQh());
								user.setZclx(unit.getZclx());
								user.setKgqk(unit.getKgqk());
								user.setYyzt(unit.getYyzt());
								user.setLsgx(unit.getLsgx());
								userDAO.save(user);
								logger.info("添加用户成功", user.getUserLoginname());
							}
						}
							break;
						case Delete:
						// 删除用户
						{
							Filter filter = new Filter();
							filter.addRule(new FilterRule(FilterConstant.EQUAL, "userLoginname", msg.getUsername()));
							filter.addRule(new FilterRule(FilterConstant.EQUAL, "enterpriseUserUseSystem", 1));
							List<User> users = userDAO.find(User.class, filter, null);
							if (users != null && users.size() > 0) {
								User user = users.get(0);
								user.setEnterpriseUserUseSystem(0);
								userDAO.update(user);
							}
						}
							break;
						}
					}
				}
			}
		};

		es.execute(task);

		//		SchedulerFactory factory = new StdSchedulerFactory();
		//		if (scheduler == null) {
		//			scheduler = factory.getScheduler();
		//			scheduler.start();
		//
		//			Filter filter = new Filter();
		//			filter.setOrder(FilterConstant.ASC);
		//			filter.setSortBy("dateType");
		//
		//			List<BillboardIndustry> rules = billboardIndustryDAO.find(BillboardIndustry.class, filter, null);
		//			for (BillboardIndustry rule : rules) {
		//				scheduleJob(rule);
		//			}
		//			// JobDetail jobDetail = new JobDetail("job_call_webservice", WEBSERVICE_AUTO_CALL,
		//			// AutoCallWebServiceJob.class);
		//			//
		//			// CronTrigger trigger = new CronTrigger("trigger_call_webservice", WEBSERVICE_AUTO_CALL, "0 0 0 1 * ?");
		//			// scheduler.scheduleJob(jobDetail, trigger);
		//		}
	}

	public void addJob(BillboardIndustry rule) throws ParseException, SchedulerException {
		scheduleJob(rule);
	}

	public void deleteJob(BillboardIndustry rule) throws SchedulerException {
		scheduler.deleteJob("job" + rule.getId(), GROUP_AUTO_PUSHING);
		scheduler.unscheduleJob("trigger" + rule.getId(), GROUP_AUTO_PUSHING);
	}

	private void scheduleJob(BillboardIndustry rule) throws ParseException, SchedulerException {
		JobDetail jobDetail = new JobDetail("job" + rule.getId(), GROUP_AUTO_PUSHING, AutoPushingJob.class);
		JobDataMap map = jobDetail.getJobDataMap();
		map.put("userIds", rule.getUsers());
		map.put("billboardTitle", rule.getBillboardTitle());
		map.put("billboardContent", rule.getBillboardContent());
		map.put("operator", rule.getOperator());
		map.put("billId", rule.getId());
		CronTrigger trigger = new CronTrigger("trigger" + rule.getId(), GROUP_AUTO_PUSHING, generateCronExpression(
				rule.getDateType(), rule.getOffset()));
		scheduler.scheduleJob(jobDetail, trigger);
	}

	public void destroy() throws SchedulerException {
		if (scheduler != null) {
			scheduler.shutdown();
		}
	}

	public String generateCronExpression(byte dateType, int offset) {

		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, 0);
		calendar.set(Calendar.DATE, 1);
		calendar.add(Calendar.DATE, offset);

		switch (dateType) {
		case BillboardConstant.DATE_TYPE_MONTHLY:
			if (calendar.get(Calendar.DATE) > 28) {
				return "0 0 0 28 * ? *";
			}
			return "0 0 0 " + calendar.get(Calendar.DATE) + " * ? *";
		case BillboardConstant.DATE_TYPE_YEARLY:
			if (calendar.get(Calendar.DATE) > 28) {
				return "0 0 0 28 " + (calendar.get(Calendar.MONTH) + 1) + " ? *";
			}
			return "0 0 0 " + calendar.get(Calendar.DATE) + " " + (calendar.get(Calendar.MONTH) + 1) + " ? *";
		case BillboardConstant.DATE_TYPE_HALF_YEARLY:
			int halfYearlMonth = calendar.get(Calendar.MONTH);
			if (halfYearlMonth > 5) {
				halfYearlMonth -= 6;
			}
			if (calendar.get(Calendar.DATE) > 28) {
				return "0 0 0 28 " + (halfYearlMonth + 1) + "," + (halfYearlMonth + 7) + " ? *";
			}
			return "0 0 0 " + calendar.get(Calendar.DATE) + " " + (halfYearlMonth + 1) + "," + (halfYearlMonth + 7)
					+ " ? *";
		default:
			int quarterlyMonth = calendar.get(Calendar.MONTH);
			if (quarterlyMonth > 8) {
				quarterlyMonth -= 9;
			} else if (quarterlyMonth > 5) {
				quarterlyMonth -= 6;
			} else if (quarterlyMonth > 2) {
				quarterlyMonth -= 3;
			}
			if (calendar.get(Calendar.DATE) > 28) {
				return "0 0 0 28 " + (quarterlyMonth + 1) + "," + (quarterlyMonth + 4) + "," + (quarterlyMonth + 7)
						+ "," + (quarterlyMonth + 10) + " ? *";
			}
			return "0 0 0 " + calendar.get(Calendar.DATE) + " " + (quarterlyMonth + 1) + "," + (quarterlyMonth + 4)
					+ "," + (quarterlyMonth + 7) + "," + (quarterlyMonth + 10) + " ? *";
		}
	}

	public void setBillboardIndustryDAO(BaseDAOInterface<BillboardIndustry> billboardIndustryDAO) {
		this.billboardIndustryDAO = billboardIndustryDAO;
	}

}
